package com.cmdi.controller;

import com.cmdi.domain.R;
import com.cmdi.domain.SysFileOps;
import com.cmdi.fileops.config.MinioClientConfig;
import com.cmdi.fileops.domain.MinIoUploadResDTO;
import com.cmdi.fileops.service.impl.MinioClientOperationImpl;
import com.cmdi.service.SysFileOpsService;
import com.cmdi.util.JwtUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;

/**
 * @Description: 文件操作
 * @Author: gaozb
 */
@Slf4j
@Api(tags = "文件操作")
@RestController
@RequestMapping("/file")
public class FileOpsController {
    private static final String STORE_SERVER_TYPE = "minio";
    private static final String MINIO_BUCKET = "cmdi-admin-biz";

    @Autowired
    private MinioClientConfig minioClientConfig;

    @Autowired
    private MinioClientOperationImpl minioClientOperation;

    @Autowired
    private SysFileOpsService sysFileOpsService;


    @ApiOperation("保留文件名上传")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "file", value = "文件")
    })
    @PreAuthorize("hasAuthority('sys_file_upload')")
    @RequestMapping(value = "/upload", method = RequestMethod.POST, headers = "content-type=multipart/form-data")
    public R upload(HttpServletRequest request, @RequestParam("file") MultipartFile files)  {
        try {
            String upPath = "p1";
            MinIoUploadResDTO minIoUploadResDTO = minioClientOperation.uploadOrignFileName(MINIO_BUCKET, upPath, files);

            String token = request.getHeader(HttpHeaders.AUTHORIZATION);
            Integer userIdFromtoken = JwtUtil.getUserIdFromtoken(token.replace("bearer ", ""));

            SysFileOps ops = new SysFileOps(null, minIoUploadResDTO.getFileName(), minIoUploadResDTO.getFileName(),
                    STORE_SERVER_TYPE, minioClientConfig.endPoint, MINIO_BUCKET, minIoUploadResDTO.getFileFullPath(),
                    new Date(), new Date(), userIdFromtoken.longValue(), null);

            sysFileOpsService.save(ops);
            return R.ok(minIoUploadResDTO, "上传成功");
        } catch (Exception e) {
            log.error("上传失败，msg={}",e.getMessage());
            return R.fail(e.getMessage());
        }
    }

    @ApiOperation("文件名加密上传")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "file", value = "文件")
    })
    @PreAuthorize("hasAuthority('sys_file_upload')")
    @RequestMapping(value = "/upload2", method = RequestMethod.POST, headers = "content-type=multipart/form-data")
    public R upload2(HttpServletRequest request, @RequestParam("file") MultipartFile files)  {
        try {
            String upPath = "p2";
            String token = request.getHeader(HttpHeaders.AUTHORIZATION);
            Integer userIdFromtoken = JwtUtil.getUserIdFromtoken(token.replace("bearer ", ""));
            MinIoUploadResDTO minIoUploadResDTO = minioClientOperation.uploadNewFileName(MINIO_BUCKET, upPath, files);
            SysFileOps ops = new SysFileOps(null, files.getOriginalFilename(), minIoUploadResDTO.getFileName(),
                    STORE_SERVER_TYPE, minioClientConfig.endPoint, MINIO_BUCKET, minIoUploadResDTO.getFileFullPath(),
                    new Date(), new Date(), userIdFromtoken.longValue(), null);
            sysFileOpsService.save(ops);
            return R.ok(minIoUploadResDTO, "上传成功");
        } catch (Exception e) {
            log.error("上传失败，msg={}",e.getMessage());
            return R.fail(e.getMessage());
        }
    }

    @ApiOperation("文件分享")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "filepath", value = "文件路径"),
            @ApiImplicitParam(name = "ex", value = "分享过期时间")
    })
    @GetMapping(value = "/share")
    public R setTime(@RequestParam("filepath") String filepath, @RequestParam("ex") Integer ex) {
        try {
            return R.ok(minioClientOperation.setShareTime(MINIO_BUCKET,filepath, ex), "更新成功");
        } catch (Exception e) {
            log.error("更新失败，msg={}",e.getMessage());
            return R.fail(e.getMessage());
        }
    }



    @ApiOperation("下载")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "fileName", value = "文件路径")
    })
    @PreAuthorize("hasAuthority('sys_file_download')")
    @RequestMapping(value = "/download", method = RequestMethod.GET)
    public R download(HttpServletResponse response, String fileName) {
        boolean b = minioClientOperation.objectExists(MINIO_BUCKET, fileName);
        if(!b) {
            return R.fail("文件不存在, " + fileName);
        }
        try {
            minioClientOperation.download(response, MINIO_BUCKET, fileName);
        } catch (Exception e) {
            log.error("下载失败，msg={}",e.getMessage());
            return R.fail("下载失败, " + fileName);
        }
        return null;
    }
}